﻿using CoreLims.Models.CoreLims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using static CoreLims.Models.CoreLims.WorkFlow;
using static CoreLims.Models.CoreLims.INV;
using Microsoft.Extensions.Logging;

namespace CoreLims.Controllers
{
    [Authorize]
    public class WorkFlowController : Controller
    {
        private readonly CoreLimsContext dbContext;
        public WorkFlowController(CoreLimsContext context)
        {
            dbContext = context;
        }

        public ViewResult SelectWorkFlow(string DomainName, string DomainId, string WorkFlowType, string ModalID)
        {
            ViewData["DomainName"] = DomainName;
            ViewData["DomainId"] = DomainId;
            ViewData["WorkFlowType"] = WorkFlowType;
            ViewData["ModalID"] = ModalID;
            return View();
        }

        public ViewResult ExamineAndApprove(string DomainName, string DomainId, string ModalID, string WorkFlowId)
        {
            WorkFlow workFlow = null;
            if (WorkFlowId != null)
                workFlow = WorkFlow.GetRuntimeWorkFlow(WorkFlowId);
            else
                workFlow = WorkFlow.GetRuntimeWorkFlow(DomainName, DomainId);

            var user = Common.User.getUserByIdentityName(dbContext, HttpContext.User.Identity.Name);
            var step = workFlow.getCurrentNextRunStepName();
            if (step == "End")
                ViewData["DisplayUser"] = false;
            else
                ViewData["DisplayUser"] = true;

            ViewData["DomainName"] = workFlow.RuntimeWorkFlow.DomainName;
            ViewData["DomainId"] = workFlow.RuntimeWorkFlow.DomainId;
            ViewData["UserName"] = user.FullName;
            ViewData["UserId"] = user.Id;
            ViewData["ModalID"] = ModalID;
            return View();
        }

        [HttpPost]
        public string Start(string WorkFlowId, string DomainName, string DomainId, string ApprovedByID, string ApprovedByName,CommonUser user,
            Func<string, string, string, WorkFlow, CommonUser,string> func)
        {
            if (WorkFlow.ExitWorkFlow(DomainName, DomainId))
                return "已经存在相应流程,在结束前不能发起新的流程！";

            var workFlow = WorkFlow.GetWorkFlow(WorkFlowId);
            if (workFlow.Definition == null)
                return "关联流程没有找到或是已删除！";

            return func(DomainId, ApprovedByID, ApprovedByName, workFlow, user);
        }

        [HttpPost]
        public void MessageReadProcessing(string RemindId) // 我的消息页面单击“已读”时触发该函数
        {
            var remind = dbContext.Remind.Where(s => s.Id == RemindId).FirstOrDefault();
            remind.ReadTime = DateTime.Now;
            dbContext.Remind.Update(remind);
            dbContext.SaveChanges();
        }

        [HttpPost]
        public void MessageReadApproval(string RemindId) // 我的消息页面单击“审批”时触发该函数
        {
            var remind = dbContext.Remind.Where(s => s.Id == RemindId).FirstOrDefault();
            remind.ReadTime = DateTime.Now;
            dbContext.Remind.Update(remind);
            dbContext.SaveChanges();
        }

        [HttpPost]
        /// <summary>
        /// 流程审批
        /// </summary>
        /// <param name="DomainName"></param>
        /// <param name="DomainId"></param>
        /// <param name="NextUserId">指定的下一步处理人ID</param>
        /// <param name="Suggestion">处理意见</param>
        /// <returns></returns>
        public string Continue(string DomainName, string DomainId, string NextUserId, string Suggestion)
        {
            var user = Common.User.getUserByIdentityName(dbContext, HttpContext.User.Identity.Name);
            WorkFlow workFlow = WorkFlow.GetRuntimeWorkFlow(DomainName, DomainId);
            if (workFlow == null) return "没有找到关联审批流程！";

            var ps = workFlow.getCurrentPreviousStep();
            if (ps != null)
            {
                if (ps.AdditionalType == "下一步处理人")
                {
                    if (ps.AdditionalData == user.Id)
                    {
                        workFlow.RunWorkFlow(handlerType:user.FullName,handlerId:user.Id, 
                            additionalType: AdditionalType.下一步处理人.ToString(), additionalData: NextUserId, Suggestion: Suggestion);
                        var rmd = dbContext.Remind.Where(s => s.WorkFlowId == workFlow.RuntimeWorkFlow.Id && s.ReadTime == null).FirstOrDefault();

                        var remind = new Remind();
                        remind.Title = rmd.Title;
                        remind.Content = rmd.Content;
                        remind.WorkFlowId = workFlow.RuntimeWorkFlow.Id;
                        remind.UserId = NextUserId;
                        //remind.UserName = ApprovedByName;
                        remind.SendRemindId = user.Id;
                        remind.SendRemindName = user.FullName;

                        rmd.ReadTime = DateTime.Now;
                        dbContext.Remind.Update(rmd); // 将上一步提醒标记为已处理
                        dbContext.Remind.Add(remind);
                        dbContext.SaveChanges();

                        var step = workFlow.getCurrentRunStepName(); // 返回运行以后的流程步骤名称，判断流程是否结束。
                        if (step == null)
                        {
                            FollowUpWork(DomainName, DomainId);
                            return "流程结束！";
                        }
                    }
                    else
                        return "您不是指定的审批人！";
                }
                else
                {
                    workFlow.RunWorkFlow(handlerType: user.FullName, handlerId: user.Id, 
                        additionalType: AdditionalType.下一步处理人.ToString(), additionalData: NextUserId, Suggestion: Suggestion);
                    return workFlow.getCurrentRunStepName();
                }
            }
            return "已审批！";
        }

        /// <summary>
        /// 审批流程结束后，进行后续相关收尾工作
        /// </summary>
        /// <param name="DomainName"></param>
        /// <param name="DomainId"></param>
        /// <returns></returns>
        private void FollowUpWork(string DomainName, string DomainId)
        {
            if (DomainName == "Inventory")
            {
                var inventory = INV.Inventory.getInventory(dbContext, DomainId);
                inventory.Status = InventoryStatus.正常.ToString();
                dbContext.Update(inventory);
                dbContext.SaveChanges();
            }
        }

    }
}
